#ifndef _xNodeType_H_
#define	_xNodeType_H_
/*------------------------------------------------------------
  2008/5/18 By YPC
   xMappingNode is of the new mapping node design (please see design document)
   There is no more VVnode and WVnode in this new design.
   "x" means X-man mapping node.
   a xMappingNode can accept abitrary kinds of connections 
   (from WOPs, VMs, collectors, or arithmetic operator
  --------------------------------------------------------------
*/
#include "DIVA_VM.h"
#include "WOP_Entry.h"
#include <string>
#include "xMappingTree.h"
#include "vmLibrary.h"
#include "xParameterPack.h"
#include "MyWord.h"

class xMappingNode;
class xParameter ;
class xOutMappingPort;
class xInMappingPort;
class xMappingTree ;

class xNodeType {

protected:
	xMappingNode * _parent ;
	bool _inport_fixed ; // true if the inports are fixed and cannot be adjusted
	bool _outport_fixed ; // true if the outports are fixed and cannot be adjusted

	std::string _name ;

public:
	enum MDSType {
		NormalMDSFormat,
		ParameterizedMDSFormat
	};
	xNodeType();
	virtual ~xNodeType();

	virtual void setParent( xMappingNode * parent );
	virtual xMappingNode * getParent() const;

	virtual void setInportFixed( bool v );
	virtual void setOutportFixed( bool v );
	virtual bool getInportFixed() const;
	virtual bool getOutportFixed() const;

	/** each type of mapping node has its own way to set up the input ports and out ports.
	    This method should always be overriden by the subclass type xNodeType */
	virtual void		setupPorts()=0 ;

	virtual std::string		getType()=0 ;

	/** each type of mapping node type can have a name. For normal vm, the name is the idname 
	    for some other mapping node, the name may be fixed or dynamic. For example, a gate mapping node
		can have its name set. A wopcollector node has a fixed name "wopcollector"
		*/
	virtual std::string getName() const;

	/** the name of a mapping node type is fixed in most of the time. However, in a gate mapping node, 
	    we allow user to set the name in the mapping dialog */
	virtual void setName( const string & name );

	/** a mapping node can map to a VM, WOP, constants...etc. 
	    This method create the mapped object */
	virtual void		createMappedObject() = 0;

	/** One mapping node has more than one output ports. When a higher level mapping node has links to the output ports 
	    of this mapping node, it may call toXParameter() to obtain the data needed from this mapping node.
		toType is the type of the inport.
		linked_op is the outport that connected to higher level mapping node
		*/
	virtual xParameter  toXParameter(std::string toType, xOutMappingPort* linked_op)=0 ;

	/** update is called when a new break point is hit by CommandAgent. It shoudl return true if the value is changed */
	virtual bool		update()=0;

	virtual std::string		toMDString(MDSType)=0; 
	virtual int			parseMDString(std::vector<std::string>& tokens, int start_index)=0;

	/** a xNodeType like xNodeType_composite has a sub structure (of type xMappingTree). This method is overridden
	   by these type of class */
	virtual xMappingTree * getxMappingTree();

	/** this abstract must be implemented by subclass. This method return true if a link is 
	    connected from right hand side. left is the outport of this node, right and rightnode
		are the inport and mapping node type that attempt to connect to this outport */
	virtual bool verify_rhs_link(xOutMappingPort *left, xInMappingPort *right, xNodeType* rightnode) = 0;

	/** this abstract must be implemented by subclass. This method return true if a link is 
	    connected from left hand side. left is the outport of leftnode that attempt to connect 
		to this mapping at inport right */
	virtual bool verify_lhs_link(xOutMappingPort *left, xNodeType* leftnode, xInMappingPort *right) = 0;


protected:
	/** this method is a common routine that will be used by verify_rhs_link and verify_rhs_link
	*/
	static bool check_valid_pair(std::string valid_pair[][2], int pair_no, std::string typeA, std::string typeB);
};
#endif
